www.gusucode.com > NGSIM 数据库换道规则提取源码程序 > NGSIM 数据库换道规则提取源码程序/shujuchulichengxu/Untitled.m

    /*
**   File:Viterbi.cpp
**   功能:给定HMM和观察序列,求最可能的状态
*/

#include "StdAfx.h"
#include <math.h>
#include "hmm.h"
#include "nrutil.h"

#define VITHUGE  100000000000.0

/**************************************************************************
** 函数名称:Viterbi
** 功能:Viterbi算法
** 参数:phmm:HMM结构指针
**       T:观察值的个数
**       O:观察序列
**       delta,psi为中间变量
**       q:求得的最佳状态序列
**       pprob:概率
**/
void Viterbi(HMM *phmm, int T, int *O, double **delta, int **psi, 
			 int *q, double *pprob)
	{
	int 	i, j;	/* 状态下标 */
	int  	t;	/* 时间下标 */	

	int	maxvalind;
	double	maxval, val;

	/* 1. 初始化  */

	for (i = 1; i <= phmm->N; i++) 
		{
		delta[1][i] = phmm->pi[i] * (phmm->B[i][O[1]]);
		psi[1][i] = 0;
		}	

	/* 2. 递归 */

	for (t = 2; t <= T; t++) 
		{
		for (j = 1; j <= phmm->N; j++) 
			{
			maxval = 0.0;
			maxvalind = 1;	
			for (i = 1; i <= phmm->N; i++) 
				{
				val = delta[t-1][i]*(phmm->A[i][j]);
				if (val > maxval) {
					maxval = val;	
					maxvalind = i;	
					}
				}

			delta[t][j] = maxval*(phmm->B[j][O[t]]);
			psi[t][j] = maxvalind; 

			}
		}

	/* 3. 终止 */

	*pprob = 0.0;
	q[T] = 1;
	for (i = 1; i <= phmm->N; i++) 
		{
		if (delta[T][i] > *pprob) 
			{
			*pprob = delta[T][i];	
			q[T] = i;
			}
		}

	/* 4. Path (state sequence) backtracking */

	for (t = T - 1; t >= 1; t--)
		q[t] = psi[t+1][q[t+1]];

	}

/**************************************************************************
** 函数名称:ViterbiLog
** 功能:Viterbi算法
** 参数:phmm:HMM结构指针
**       T:观察值的个数
**       O:观察序列
**       delta,psi为中间变量
**       q:求得的最佳状态序列
**       pprob:概率
**/
void ViterbiLog(HMM *phmm, int T, int *O, double **delta, int **psi,
				int *q, double *pprob)
	{
	int     i, j;   /* 状态下标 */
	int     t;      /* 时间下标 */

	int     maxvalind;
	double  maxval, val;
	double  **biot;

	/* 0. 预处理 */

	for (i = 1; i <= phmm->N; i++) 
		phmm->pi[i] = log(phmm->pi[i]);
	for (i = 1; i <= phmm->N; i++) 
		for (j = 1; j <= phmm->N; j++) 
			{
			phmm->A[i][j] = log(phmm->A[i][j]);
			}

		biot = dmatrix(1, phmm->N, 1, T);
		for (i = 1; i <= phmm->N; i++) 
			for (t = 1; t <= T; t++) 
				{
				biot[i][t] = log(phmm->B[i][O[t]]);
				}

			/* 1. 初始化  */

			for (i = 1; i <= phmm->N; i++) 
				{
				delta[1][i] = phmm->pi[i] + biot[i][1];
				psi[1][i] = 0;
				}

			/* 2. 递归 */

			for (t = 2; t <= T; t++) 
				{
				for (j = 1; j <= phmm->N; j++) 
					{
					maxval = -VITHUGE;
					maxvalind = 1;
					for (i = 1; i <= phmm->N; i++) 
						{
						val = delta[t-1][i] + (phmm->A[i][j]);
						if (val > maxval) 
							{
							maxval = val;
							maxvalind = i;
							}
						}

					delta[t][j] = maxval + biot[j][t]; 
					psi[t][j] = maxvalind;

					}
				}

			/* 3. 终止 */

			*pprob = -VITHUGE;
			q[T] = 1;
			for (i = 1; i <= phmm->N; i++) 
				{
				if (delta[T][i] > *pprob) 
					{
					*pprob = delta[T][i];
					q[T] = i;
					}
				}


			/* 4. 回溯 */

			for (t = T - 1; t >= 1; t--)
				q[t] = psi[t+1][q[t+1]];

	}